package lxs.tool.liberator.work.core;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import lxs.tool.liberator.common.base.enums.code.KeyWord;
import lxs.tool.liberator.common.base.enums.code.Template;
import lxs.tool.liberator.common.utils.Dater;
import lxs.tool.liberator.common.utils.ZipUtil;
import lxs.tool.liberator.work.mapper.*;
import lxs.tool.liberator.work.param.out.ParamTree;
import lxs.tool.liberator.work.pojo.*;
import lxs.tool.liberator.work.pojo.Class;
import org.apache.commons.lang.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import java.io.*;
import java.util.*;
import java.util.regex.Pattern;

@Component
public class CodeMan {
    private static final Map<String, String> codeMap = new HashMap<>();

    {
        try {
            ClassPathResource classPathResource = new ClassPathResource("template/code.xml");
            InputStream resourceAsStream = classPathResource.getInputStream();
            read(resourceAsStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Autowired
    private ClassMapper classMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ColumnMapper columnMapper;
    @Autowired
    private InterfaceMapper interfaceMapper;
    @Autowired
    private ParamMapper paramMapper;
    @Autowired
    private EntityMapper entityMapper;
    @Autowired
    private FieldMapper fieldMapper;

    public File generate(Project project) throws Exception {
        File liberator = new File("./liberator");
        removeFile(liberator);
        List<Class> projectClass = classMapper.getProjectClass(project.getId());
        String projectName = project.getName();
        File aop = new File("./liberator/" + project.getGroupId().replace(".", "/") +
                "/" + project.getName() + "/common/base/aspect/Aop.java");

        File response = new File("./liberator/" + project.getGroupId().replace(".", "/")
                + "/" + project.getName() + "/common/base/result/Response.java");

        File app = new File("./liberator/" + project.getGroupId().replace(".", "/") + "/" + projectName + "Application.java");

        writeCode(aop, aopCode(project.getGroupId() + "." + projectName));
        writeCode(response, responseCode(project.getGroupId() + "." + projectName));
        writeCode(app, appCode(project.getGroupId() + "." + projectName,
                projectName.replaceFirst(projectName.charAt(0) + "", (projectName.charAt(0) + "").toUpperCase())));
        for (Class clazz : projectClass) {
            createCode(project, clazz);
        }

        File re = new File("./liberator.zip");
        ZipUtil.toZip(liberator, new FileOutputStream(re), true);
        return re;
    }

    public File downloadClassJava(String id) throws Exception {
        Class aClass = classMapper.selectById(id);
        String s = pojoCode(aClass);
        File file = new File("./" + aClass.getNameInJava() + ".java");
        writeCode(file, s);
        return file;
    }

    public File downloadInterfaceJava(String id) throws Exception {
        File liberator = new File("./liberator");
        removeFile(liberator);
        Interface anInterface = interfaceMapper.selectById(id);
        String classId = anInterface.getClassId();
        Class aClass = classMapper.selectById(classId);
        Project mainProject = projectMapper.getMainProject();
        createCode(mainProject, aClass);
        File file = new File("./liberator.zip");
        ZipUtil.toZip(liberator, new FileOutputStream(file), true);
        return file;
    }

    private void removeFile(File file) {
        if (!file.exists()) return;
        if (file.isFile()) {
            file.delete();
            return;
        }
        File[] files = file.listFiles();
        for (File f : files) {
            removeFile(f);
        }
        file.delete();
    }

    /**
     * 读取代码模板
     *
     * @param inputStream 模板文件输入流
     * @throws Exception i dont know
     */
    private void read(InputStream inputStream) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document document = db.parse(inputStream);
        Element documentElement = document.getDocumentElement();
        NodeList childNodes = documentElement.getChildNodes();
        int length = childNodes.getLength();
        for (int i = 0; i < length; i++) {
            Node item = childNodes.item(i);
            String nodeName = item.getNodeName();
            String nodeValue = item.getTextContent().replaceAll("        ", "").trim();
            codeMap.put(nodeName, nodeValue);
        }
    }

    /**
     * 根据指定的模板和值,生成对应的代码
     *
     * @param map 必须要有TEMPLATE值,INDEX不存在则默认为0
     */
    private String create(Map<String, String> map) throws Exception {
        String template = map.get(Template.TEMPLATE());
        String index = map.get(Template.INDEX());
        int in;
        if (template == null || template.equals("")) {
            throw new Exception("请指定TEMPLATE值");
        }
        if (index == null || index.equals("")) in = 0;
        else in = Integer.parseInt(index);
        String code = codeMap.get(template);
        for (String key : map.keySet()) {
            if (key.equals("TEMPLATE") || key.equals("INDEX")) {
                continue;
            }
            if (template.equals("column") || template.equals("condition")) {
                code = code.split("\\|\n")[in];
            }
            code = code.replaceAll(Pattern.quote("[" + key + "]"), map.get(key) + "");
        }
        return code;
    }

    private void createCode(Project project, Class clazz) throws Exception {
        String start = "/" + project.getGroupId().replace(".", "/") + "/" + project.getName() + "/work";
        File pojo = new File("./liberator/" + start + "/pojo/" + clazz.getNameInJava() + ".java");
        File service = new File("./liberator/" + start + "/service/" + clazz.getNameInJava() + "Service.java");
        File imp = new File("./liberator/" + start + "/service/imp/" + clazz.getNameInJava() + "ServiceImp.java");
        File mapper = new File("./liberator/" + start + "/mapper/" + clazz.getNameInJava() + "Mapper.java");
        File controller = new File("./liberator/" + start + "/controller/" + clazz.getNameInJava() + "Controller.java");
        File xml = new File("./liberator/" + "resources/mapper/work/" + clazz.getNameInJava() + "Mapper.xml");
        writeCode(pojo, pojoCode(clazz));
        writeCode(service, serviceCode(project, clazz));
        writeCode(imp, serviceImpCode(project, clazz));
        writeCode(controller, controllerCode(project, clazz));
        writeCode(mapper, mapperCode(project, clazz));
        writeCode(xml, xmlCode(project, clazz));
    }

    private void writeCode(File file, String code) throws IOException {
        if (!file.exists()) {
            String path = file.getPath();
            path = path.replace("\\", "/");
            String substring = path.substring(0, path.lastIndexOf("/"));
            File dir = new File(substring);
            if (!dir.exists()) dir.mkdirs();
            file.createNewFile();
        }
        Writer writer = new FileWriter(file);
        writer.write(code);
        writer.flush();
        writer.close();
    }

    /**
     * 生成pojo代码
     *
     * @param clazz class的信息
     * @return pojo代码
     * @throws Exception 命名冲突
     */
    private String pojoCode(Class clazz) throws Exception {
        List<Column> listByClassId = columnMapper.getListByClassId(clazz.getId());
        List<String> columns = new ArrayList<>();
        List<String> dependencyList = new ArrayList<>();
        for (Column c : listByClassId) {
            columns.add(fieldCode(c, clazz.getNameInDb(), dependencyList));
        }
        String fields = StringUtils.join(columns, "\n");
        dependencyList.add("import com.baomidou.mybatisplus.annotation.TableName;");
        dependencyList.add("import lombok.Data;");
        dependencyList.add("import lombok.experimental.Accessors;");
        String dependencies = StringUtils.join(dependencyList, "\n");
        Project mainProject = projectMapper.getMainProject();
        String s = mainProject.getGroupId() + "." + mainProject.getName();
        String packagePath = s + ".work.pojo";
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.pojo);
        map.put(Template.Pojo.className, clazz.getNameInJava());
        map.put(Template.Pojo.dependencies, dependencies);
        map.put(Template.Pojo.fields, fields);
        map.put(Template.Pojo.tableName, clazz.getNameInDb());
        map.put(Template.Pojo.comment, clazz.getComment());
        map.put(Template.Pojo.packagePath, packagePath);
        return clear(create(map));
    }

    private String mapperCode(Project project, Class clazz) throws Exception {
        String groupId = project.getGroupId();
        String name = project.getName();
        String path = groupId + "." + name + ".work.service";
        Set<String> dependencies = new HashSet<>();
        dependencies.add("import com.baomidou.mybatisplus.core.mapper.BaseMapper;");
        dependencies.add("import org.apache.ibatis.annotations.Mapper;");
        dependencies.add("import org.apache.ibatis.annotations.Param;");
        dependencies.add("import " + groupId + "." + name + ".common.base.result.Response;");
        List<String> functionList = new ArrayList<>();
        List<String> paramList = new ArrayList<>();
        QueryWrapper<Interface> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", project.getId());
        queryWrapper.eq("class_id", clazz.getId());
        List<Interface> interfaces = interfaceMapper.selectList(queryWrapper);
        for (Interface i : interfaces) {
            String fName = i.getName();
            String params;
            Param param = paramMapper.getInterfaceParamByWhat(i.getId(), "1");
            if (param == null) {
                params = "";
            } else {
                switch (param.getKey()) {
                    case "2":
                        Entity entity = entityMapper.selectById(param.getName());
                        param.setName(entity.getName());
                        dependencies.add("import " + groupId + "." + name + ".work.param.in." + param.getName() + ";");
                        params = param.getName() + " " + getParamName(param.getName());
                        break;
                    case "5":
                        Class aClass = classMapper.selectById(param.getName());
                        param.setName(aClass.getNameInJava());
                        dependencies.add("import " + groupId + "." + name + ".work.pojo." + param.getName() + ";");
                        params = param.getName() + " " + getParamName(param.getName());
                        break;
                    case "4":
                        QueryWrapper<Param> wrapper = new QueryWrapper<>();
                        wrapper.eq("belong", param.getId());
                        List<Param> list = paramMapper.selectList(wrapper);
                        for (Param p : list) {
                            String type = p.getType();
                            if (p.getKey().equals("3")) {
                                type = "List<" + type + ">";
                            }
                            paramList.add("@Param(\"" + p.getName() + "\")" + type + " " + p.getName());
                        }
                        params = StringUtils.join(paramList, ",");
                        break;
                    case "3":
                        dependencies.add("import java.util.ArrayList;");
                        dependencies.add("import java.util.List;");
                        params = "@Param(\"" + param.getName() + "\")" + "List<" + param.getType() + "> " + param.getName();
                        break;
                    default:
                        params = "@Param(\"" + param.getName() + "\")" + param.getType() + " " + param.getName();
                        break;
                }
            }
            if (param == null) {
                functionList.add("void " + fName + "(" + params + ");");
            } else {
                if (param.getKey().equals("3")) {
                    functionList.add("List<" + param.getType() + "> " + fName + "(" + params + ");");
                }
                else if (param.getKey().equals("2") || param.getKey().equals("5")) {
                    functionList.add(param.getName() + " " + fName + "(" + params + ");");
                }else {
                    functionList.add(param.getType() + " " + fName + "(" + params + ");");
                }
            }
            paramList.clear();
        }
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.mapper);
        map.put(Template.Mapper.className, clazz.getNameInJava() + "Mapper");
        map.put(Template.Mapper.comment, "/**\n" +
                " * @author liberator\n" +
                " * @date " + Dater.format(new Date()) + "\n" +
                " * @email 3451743380@qq.com\n" +
                " */");
        map.put(Template.Mapper.pojo, clazz.getNameInJava());
        map.put(Template.Mapper.packagePath, path);
        map.put(Template.Mapper.dependencies, StringUtils.join(dependencies, "\n"));
        map.put(Template.Mapper.functions, StringUtils.join(functionList, "\n"));
        return clear(create(map));
    }

    private String serviceCode(Project project, Class clazz) throws Exception {
        String groupId = project.getGroupId();
        String name = project.getName();
        String path = groupId + "." + name + ".work.service";
        Set<String> dependencies = new HashSet<>();
        dependencies.add("import " + groupId + "." + name + ".common.base.result.Response;");
        List<String> functionList = new ArrayList<>();
        List<String> paramList = new ArrayList<>();
        QueryWrapper<Interface> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", project.getId());
        queryWrapper.eq("class_id", clazz.getId());
        List<Interface> interfaces = interfaceMapper.selectList(queryWrapper);
        for (Interface i : interfaces) {
            String fName = i.getName();
            String params;
            Param param = paramMapper.getInterfaceParamByWhat(i.getId(), "1");
            if (param == null) {
                params = "";
            } else {
                switch (param.getKey()) {
                    case "2":
                        Entity entity = entityMapper.selectById(param.getName());
                        ParamTree tree = JSON.parseObject(param.getJson(), ParamTree.class);
                        param.setName(entity.getName());
                        params = param.getName() + " " + getParamName(param.getName());
                        dependencies.add("import " + groupId + "." + name + ".work.param.in." + param.getName() + ";");
                        String s = paramCode(entity, tree.getWhat());
                        String start = "/" + project.getGroupId().replace(".", "/") + "/" + project.getName() + "/work";
                        File paramFile = new File("./liberator/" + start + "/param/" + (param.getWhat().equals("1") ? "in/" : "out/") + param.getName() + ".java");
                        writeCode(paramFile, s);
                        break;
                    case "5":
                        Class aClass = classMapper.selectById(param.getName());
                        param.setName(aClass.getNameInJava());
                        dependencies.add("import " + groupId + "." + name + ".work.pojo." + param.getName() + ";");
                        params = param.getName() + " " + getParamName(param.getName());
                        break;
                    case "4":
                        QueryWrapper<Param> wrapper = new QueryWrapper<>();
                        wrapper.eq("belong", param.getId());
                        List<Param> list = paramMapper.selectList(wrapper);
                        for (Param p : list) {
                            String type = p.getType();
                            if (p.getKey().equals("3")) {
                                type = "List<" + type + ">";
                            }
                            paramList.add(type + " " + p.getName());
                        }
                        params = StringUtils.join(paramList, ",");
                        break;
                    case "3":
                        dependencies.add("import java.util.ArrayList;");
                        dependencies.add("import java.util.List;");
                        params = "List<" + param.getType() + "> " + param.getName();
                        break;
                    default:
                        params = param.getType() + " " + param.getName();
                        break;
                }
            }
            functionList.add("Response " + fName + "(" + params + ");");
            paramList.clear();
        }
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.service);
        map.put(Template.Service.className, clazz.getNameInJava() + "Service");
        map.put(Template.Service.comment, "/**\n" +
                " * @author liberator\n" +
                " * @date " + Dater.format(new Date()) + "\n" +
                " * @email 3451743380@qq.com\n" +
                " */");
        map.put(Template.Service.packagePath, path);
        map.put(Template.Service.dependencies, StringUtils.join(dependencies, "\n"));
        map.put(Template.Service.functions, StringUtils.join(functionList, "\n"));
        return clear(create(map));
    }

    private String serviceImpCode(Project project, Class clazz) throws Exception {
        String groupId = project.getGroupId();
        String name = project.getName();
        String path = groupId + "." + name + ".work.service.imp";
        Set<String> dependencies = new HashSet<>();
        dependencies.add("import org.springframework.beans.factory.annotation.Autowired;");
        dependencies.add("import org.springframework.stereotype.Service;");
        dependencies.add("import " + groupId + "." + name + ".common.base.result.Response;");
        dependencies.add("import " + groupId + "." + name + ".work.mapper." + clazz.getNameInJava() + "Mapper;");
        List<String> functionList = new ArrayList<>();
        List<String> fieldList = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.filed);
        map.put(Template.Field.annotations, "@Autowired");
        map.put(Template.Field.fieldName, nameCamel(clazz.getNameInDb()) + "Mapper");
        map.put(Template.Field.modifier, "private");
        map.put(Template.Field.comment, "");
        map.put(Template.Field.type, clazz.getNameInJava() + "Mapper");
        fieldList.add(clear(create(map)));
        map.clear();
        List<String> paramList = new ArrayList<>();
        QueryWrapper<Interface> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", project.getId());
        queryWrapper.eq("class_id", clazz.getId());
        List<Interface> interfaces = interfaceMapper.selectList(queryWrapper);
        for (Interface i : interfaces) {
            String params;
            Param param = paramMapper.getInterfaceParamByWhat(i.getId(), "1");
            if (param == null) {
                params = "";
            } else {
                switch (param.getKey()) {
                    case "2":
                        Entity entity = entityMapper.selectById(param.getName());
                        param.setName(entity.getName());
                        dependencies.add("import " + groupId + "." + name + ".work.param.in." + param.getName() + ";");
                        params = param.getName() + " " + getParamName(param.getName());
                        break;
                    case "5":
                        Class aClass = classMapper.selectById(param.getName());
                        param.setName(aClass.getNameInJava());
                        dependencies.add("import " + groupId + "." + name + ".work.pojo." + param.getName() + ";");
                        params = param.getName() + " " + getParamName(param.getName());
                        break;
                    case "4":
                        QueryWrapper<Param> wrapper = new QueryWrapper<>();
                        wrapper.eq("belong", param.getId());
                        List<Param> list = paramMapper.selectList(wrapper);
                        for (Param p : list) {
                            String type = p.getType();
                            if (p.getKey().equals("3")) {
                                type = "List<" + type + ">";
                            }
                            paramList.add(type + " " + p.getName());
                        }
                        params = StringUtils.join(paramList, ",");
                        break;
                    case "3":
                        dependencies.add("import java.util.ArrayList;");
                        dependencies.add("import java.util.List;");
                        params = "List<" + param.getType() + "> " + param.getName();
                        break;
                    default:
                        params = param.getType() + " " + param.getName();
                        break;
                }
            }
            map.put(Template.TEMPLATE(), Template.Templates.function);
            map.put(Template.Function.annotations, "@Override");
            map.put(Template.Function.functionName, i.getName());
            map.put(Template.Function.modifier, "private");
            map.put(Template.Function.params, params);
            Param byWhat = paramMapper.getInterfaceParamByWhat(i.getId(), "0");
            if (byWhat == null) {
                map.put(Template.Function.body,
                        nameCamel(clazz.getNameInDb()) + "Mapper." + i.getName() + "(" + params + ");\n"
                                + "return Response.success();");
            } else {
                map.put(Template.Function.body,
                        "return Response.send(" + nameCamel(clazz.getNameInDb()) + "Mapper." + i.getName() + "(" + getParamName(param.getName()) + ")" + ");");
            }
            map.put(Template.Function.type, "Response");
            map.put(Template.Function.comment, " /**\n" +
                    "     * " + i.getName() + "接口实现代码\n" +
                    "     * @return Response\n" +
                    "     */");
            functionList.add(clear(create(map)));
            map.clear();
            paramList.clear();
        }
        map.put(Template.TEMPLATE(), Template.Templates.imp);
        map.put(Template.Imp.className, clazz.getNameInJava() + "ServiceImp");
        map.put(Template.Imp.packagePath, path);
        map.put(Template.Imp.dependencies, StringUtils.join(dependencies, "\n"));
        map.put(Template.Imp.comment, "/**\n" +
                " * @author liberator\n" +
                " * @date " + Dater.format(new Date()) + "\n" +
                " * @email 3451743380@qq.com\n" +
                " */");
        map.put(Template.Imp.fields, StringUtils.join(fieldList, "\n"));
        map.put(Template.Imp.functions, StringUtils.join(functionList, "\n"));
        map.put(Template.Imp.serviceName, clazz.getNameInJava() + "Service");
        return clear(create(map));
    }

    private String controllerCode(Project project, Class clazz) throws Exception {
        String groupId = project.getGroupId();
        String name = project.getName();
        String path = groupId + "." + name + ".work.service.imp";
        Set<String> dependencies = new HashSet<>();
        dependencies.add("import org.springframework.beans.factory.annotation.Autowired;");
        dependencies.add("import org.springframework.web.bind.annotation.RequestMapping;");
        dependencies.add("import org.springframework.web.bind.annotation.RestController;");
        dependencies.add("import " + groupId + "." + name + ".common.base.result.Response;");
        dependencies.add("import " + groupId + "." + name + ".work.service." + clazz.getNameInJava() + "Service;");
        List<String> functionList = new ArrayList<>();
        List<String> fieldList = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.filed);
        map.put(Template.Field.annotations, "@Autowired");
        map.put(Template.Field.fieldName, nameCamel(clazz.getNameInDb()) + "Service");
        map.put(Template.Field.modifier, "private");
        map.put(Template.Field.comment, "");
        map.put(Template.Field.type, clazz.getNameInJava() + "Service");
        fieldList.add(clear(create(map)));
        map.clear();
        List<String> paramList = new ArrayList<>();
        QueryWrapper<Interface> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", project.getId());
        queryWrapper.eq("class_id", clazz.getId());
        List<Interface> interfaces = interfaceMapper.selectList(queryWrapper);
        for (Interface i : interfaces) {
            String params;
            Param param = paramMapper.getInterfaceParamByWhat(i.getId(), "1");
            if (param == null) {
                params = "";
            } else {
                switch (param.getKey()) {
                    case "2":
                        Entity entity = entityMapper.selectById(param.getName());
                        param.setName(entity.getName());
                        dependencies.add("import " + groupId + "." + name + ".work.param.in." + param.getName() + ";");
                        params = param.getName() + " " + getParamName(param.getName());
                        break;
                    case "5":
                        Class aClass = classMapper.selectById(param.getName());
                        param.setName(aClass.getNameInJava());
                        dependencies.add("import " + groupId + "." + name + ".work.pojo." + param.getName() + ";");
                        params = param.getName() + " " + getParamName(param.getName());
                        break;
                    case "4":
                        QueryWrapper<Param> wrapper = new QueryWrapper<>();
                        wrapper.eq("belong", param.getId());
                        List<Param> list = paramMapper.selectList(wrapper);
                        for (Param p : list) {
                            String type = p.getType();
                            if (p.getKey().equals("3")) {
                                type = "List<" + type + ">";
                            }
                            paramList.add(type + " " + p.getName());
                        }
                        params = StringUtils.join(paramList, ",");
                        break;
                    case "3":
                        dependencies.add("import java.util.ArrayList;");
                        dependencies.add("import java.util.List;");
                        params = "List<" + param.getType() + "> " + param.getName();
                        break;
                    default:
                        params = param.getType() + " " + param.getName();
                        break;
                }
            }
            map.put(Template.TEMPLATE(), Template.Templates.function);
            switch (i.getMethod()) {
                case "GET":
                    map.put(Template.Function.annotations, "@GetMapping(\"" + i.getName() + "\")");
                    dependencies.add("import org.springframework.web.bind.annotation.GetMapping;");
                    break;
                case "DELETE":
                    map.put(Template.Function.annotations, "@DeleteMapping(\"" + i.getName() + "\")");
                    dependencies.add("import org.springframework.web.bind.annotation.DeleteMapping;");
                    break;
                case "POST":
                    map.put(Template.Function.annotations, "@PostMapping(\"" + i.getName() + "\")");
                    dependencies.add("import org.springframework.web.bind.annotation.PostMapping;");
                    break;
                case "PUT":
                    map.put(Template.Function.annotations, "@PutMapping(\"" + i.getName() + "\")");
                    dependencies.add("import org.springframework.web.bind.annotation.PutMapping;");
                    break;
                default:
                    map.put(Template.Function.annotations, "@RequestMapping(\"" + i.getName() + "\")");
                    break;
            }
            map.put(Template.Function.functionName, i.getName());
            map.put(Template.Function.modifier, "public");
            if (param != null && (param.getKey().equals("3") || param.getKey().equals("2") || param.getKey().equals("5"))) {
                map.put(Template.Function.params, "@RequestBody " + params);
            } else map.put(Template.Function.params, params);
            if (StringUtils.isEmpty(params)) {
                map.put(Template.Function.body,
                        "return " + nameCamel(clazz.getNameInDb()) + "Service." + i.getName() + "(" + getParamName(param.getName()) + ");");
            } else {
                map.put(Template.Function.body,
                        "return " + nameCamel(clazz.getNameInDb()) + "Service." + i.getName() + "();");
            }
            map.put(Template.Function.type, "Response");
            map.put(Template.Function.comment, "  /**\n" +
                    "     * " + i.getRemark() + "\n" +
                    "     * @return Response\n" +
                    "     */");
            functionList.add(clear(create(map)));
            map.clear();
            paramList.clear();
        }
        map.put(Template.TEMPLATE(), Template.Templates.controller);
        map.put(Template.Controller.className, clazz.getNameInJava() + "Controller");
        map.put(Template.Controller.packagePath, path);
        map.put(Template.Controller.dependencies, StringUtils.join(dependencies, "\n"));
        map.put(Template.Controller.comment, "/**\n" +
                " * @author liberator\n" +
                " * @date " + Dater.format(new Date()) + "\n" +
                " * @email 3451743380@qq.com\n" +
                " */");
        map.put(Template.Controller.fields, StringUtils.join(fieldList, "\n"));
        map.put(Template.Controller.functions, StringUtils.join(functionList, "\n"));
        map.put(Template.Controller.url, "work/" + clazz.getNameInJava() + "Service");
        return clear(create(map));
    }

    private String paramCode(Entity entity, String what) throws Exception {
        List<String> columns = new ArrayList<>();
        List<String> dependencyList = new ArrayList<>();
        dependencyList.add("import lombok.Data;");
        dependencyList.add("import lombok.experimental.Accessors;");
        List<Field> fieldList = fieldMapper.getByEId(entity.getId());
        for (Field field : fieldList) {
            if (field.getName().matches("List<[A-Za-z0-9_]+>")) {
                dependencyList.add("import java.util.List;");
            }
            Map<String, String> map = new HashMap<>();
            map.put(Template.TEMPLATE(), Template.Templates.filed);
            map.put(Template.Field.type, field.getType());
            map.put(Template.Field.fieldName, field.getName());
            map.put(Template.Field.modifier, "private");
            map.put(Template.Field.comment, field.getRemark());
            if (KeyWord.isMysqlKeyWord(field.getName())) {
                map.put(Template.Field.annotations, "@TableField(`" + field.getName() + "`)");
                dependencyList.add("import com.baomidou.mybatisplus.annotation.TableField;");
            } else map.put(Template.Field.annotations, "");
            columns.add(clear(create(map)));
        }
        String fields = StringUtils.join(columns, "\n");
        String dependencies = StringUtils.join(dependencyList, "\n");
        Project mainProject = projectMapper.getMainProject();
        String s = mainProject.getGroupId() + "." + mainProject.getName();
        String packagePath;
        if (what.equals("1")) {
            packagePath = s + ".work.param.in";
        } else {
            packagePath = s + ".work.param.out";
        }
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.param);
        map.put(Template.Param.className, entity.getName());
        map.put(Template.Param.dependencies, dependencies);
        map.put(Template.Param.fields, fields);
        map.put(Template.Param.comment, entity.getRemark());
        map.put(Template.Param.packagePath, packagePath);
        return clear(create(map));
    }

    /**
     * 生成属性代码
     *
     * @param column         属性信息
     * @param classname      表名
     * @param dependencyList 上级依赖列表引用
     * @return 代码
     * @throws Exception 命名冲突
     */
    private String fieldCode(Column column, String classname, List<String> dependencyList) throws Exception {
        String filedName = column.getFiledName();
        String tableField = "@TableField(\"`[name]`\")";
        if (KeyWord.isJavaKeyWord(filedName)) {
            throw new Exception(classname + "表中的字段" + column.getColumnName() + "定义的别名" + filedName + "为java关键字");
        }
        if (KeyWord.isMysqlKeyWord(filedName)) {
            dependencyList.add("import com.baomidou.mybatisplus.annotation.TableField;");
            tableField = tableField.replaceFirst(Pattern.quote("[name]"), filedName);
        } else tableField = "";
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.filed);
        map.put(Template.Field.fieldName, filedName);
        map.put(Template.Field.modifier, "private");
        map.put(Template.Field.type, column.getFiledType());
        if (StringUtils.isEmpty(column.getComment()))
            map.put(Template.Field.comment, "");
        else {
            map.put(Template.Field.comment, "/**\n" +
                    " * " + column.getComment() + "\n" +
                    " */");
        }
        map.put(Template.Field.annotations, tableField);
        return clear(create(map));
    }

    private String xmlCode(Project project, Class clazz) throws Exception {
        List<Interface> classInterface = interfaceMapper.getClassInterface(clazz.getId());
        List<String> node = new ArrayList<>();
        for (Interface i : classInterface) {
            List<Param> interfaceParam = paramMapper.getInterfaceParam(i.getId());
            switch (i.getAction()) {
                case "SELECT":
                    Param in = interfaceParam.get(0).getWhat().equals("1") ? interfaceParam.get(0) : interfaceParam.get(1);
                    Param out = interfaceParam.get(0).getWhat().equals("0") ? interfaceParam.get(0) : interfaceParam.get(1);
                    node.add(selectSql(out, in));
                    break;
                case "DELETE":
                    node.add(deleteSql(interfaceParam.get(0)));
                    break;
                case "UPDATE":
                    node.add(updateSql(interfaceParam.get(0)));
                    break;
                case "INSERT":
                    node.add(insertSql(interfaceParam.get(0)));
                    break;
            }
        }
        String s = project.getGroupId() + "." + project.getName();
        String mapperPath = s + ".work.mapper." + clazz.getNameInJava() + ".Mapper";
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.xml);
        map.put(Template.Xml.mapperPath, mapperPath);
        map.put(Template.Xml.sql, StringUtils.join(node, "\n"));
        return clear(create(map));
    }

    private String insertSql(Param param) throws Exception {
        ParamTree tree = JSON.parseObject(param.getJson(), ParamTree.class);
        if (!tree.getWhat().equals("1")) {
            throw new Exception("insert操作的接口的参数只能是入参");
        }
        if (!(tree.getKey().equals("2") || tree.getKey().equals("4"))) {
            throw new Exception("insert操作的接口的入参只能是对象或者是参数组合");
        }
        String name = entityMapper.selectById(tree.getName()).getName();
        tree.setName(name);
        param.setName(name);
        String interfaceId = tree.getInterfaceId();
        Interface anInterface = interfaceMapper.selectById(interfaceId);
        String classId = anInterface.getClassId();
        Class aClass = classMapper.selectById(classId);
        List<String> columns = new ArrayList<>();
        List<String> values = new ArrayList<>();
        List<ParamTree> children = tree.getChildren();
        for (ParamTree child : children) {
            String linkColumn = child.getLinks().get(0).getLinks().get(0).getLink();
            Column column = columnMapper.selectById(linkColumn);
            String valueName = child.getName();
            columns.add("`" + column.getColumnName() + "`");
            values.add("#{" + tree.getName() + "." + valueName + "}");
        }
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.insert);
        map.put(Template.Insert.columns, StringUtils.join(columns, ","));
        map.put(Template.Insert.tableName, aClass.getNameInDb());
        map.put(Template.Insert.functionName, anInterface.getName());
        map.put(Template.Insert.values, StringUtils.join(values, ","));
        return create(map);
    }

    private String deleteSql(Param param) throws Exception {
        ParamTree tree = JSON.parseObject(param.getJson(), ParamTree.class);
        if (!tree.getWhat().equals("1")) {
            throw new Exception("delete操作的接口的参数只能是入参");
        }
        String interfaceId = tree.getInterfaceId();
        Interface anInterface = interfaceMapper.selectById(interfaceId);
        String classId = anInterface.getClassId();
        Class aClass = classMapper.selectById(classId);
        List<String> conditions = new ArrayList<>();
        if (tree.getKey().equals("2") || tree.getKey().equals("4")) {
            if (tree.getKey().equals("2")) {
                tree.setName(entityMapper.selectById(tree.getName()).getName());
            }
            List<ParamTree> children = tree.getChildren();
            for (ParamTree child : children) {
                child.setInterfaceId(tree.getInterfaceId());
                String cond = getConditions(child);
                if (StringUtils.isNotEmpty(cond)) conditions.add(cond);
            }
        } else {
            String cond = getConditions(tree);
            if (StringUtils.isNotEmpty(cond)) conditions.add(cond);
        }
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.delete);
        map.put(Template.Delete.conditions, StringUtils.join(conditions, " AND "));
        map.put(Template.Delete.tableName, aClass.getNameInDb());
        map.put(Template.Delete.functionName, anInterface.getName());
        return create(map);
    }

    private String getResults(ParamTree tree, List<String> joins, String mainTable) throws Exception {
        List<ParamTree> links = tree.getLinks();
        List<String> re = new ArrayList<>();
        Map<String, Integer> count = new HashMap<>();
        List<Map<String, String>> joinBody = new ArrayList<>();
        for (ParamTree child : links) {
            if (child.getKey().equals("link")) {
                String func = child.getFunc();
                if (func.equals("0")) {
                    ParamTree column = child.getLinks().get(0);
                    String columnId = column.getLink();
                    Column linkColumn = columnMapper.selectById(columnId);
                    Class aClass = classMapper.selectById(linkColumn.getClassId());
                    if (column.getKey().equals("col")) {
                        re.add("`" + aClass.getNameInDb() + "`.`" + linkColumn.getColumnName() + "` AS `" + tree.getName() + "`");
                    }
                    if (column.getKey().equals("elseCol")) {
                        String joinColumnId = column.getValue();
                        Column joinColumn = columnMapper.selectById(joinColumnId);
                        Class joinClass = classMapper.selectById(linkColumn.getClassId());
                        Integer c = count.get(aClass.getNameInDb());
                        if (c == null) {
                            re.add("`" + aClass.getNameInDb() + "`.`" + linkColumn.getColumnName() + "` AS `" + tree.getName() + "`");
                            Map<String, String> map = new HashMap<>();
                            map.put(Template.TEMPLATE(), Template.Templates.join);
                            map.put(Template.Join.how, "LEFT");
                            map.put(Template.Join.joinTableAs, joinClass.getNameInDb());
                            map.put(Template.Join.joinColumnName, joinColumn.getColumnName());
                            map.put(Template.Join.mainTable, mainTable);
                            map.put(Template.Join.mainColumn, linkColumn.getColumnName());
                            map.put(Template.Join.joinTableName, joinClass.getNameInDb());
                            joinBody.add(map);
                        }
                    }
                } else {
                    String s = func + "(";
                    List<String> params = new ArrayList<>();
                    List<ParamTree> childLinks = child.getLinks();
                    for (ParamTree childLink : childLinks) {
                        String columnId = childLink.getLink();
                        Column linkColumn = columnMapper.selectById(columnId);
                        Class aClass = classMapper.selectById(linkColumn.getClassId());
                        if (childLink.getKey().equals("col")) {
                            params.add("`" + aClass.getNameInDb() + "`.`" + linkColumn.getColumnName() + "` AS `" + tree.getName() + "`");
                        }
                        if (childLink.getKey().equals("elseCol")) {
                            String joinColumnId = childLink.getValue();
                            Column joinColumn = columnMapper.selectById(joinColumnId);
                            Class joinClass = classMapper.selectById(linkColumn.getClassId());
                            Integer c = count.get(aClass.getNameInDb());
                            if (c == null) {
                                params.add("`" + aClass.getNameInDb() + "`.`" + linkColumn.getColumnName() + "` AS `" + tree.getName() + "`");
                                Map<String, String> map = new HashMap<>();
                                map.put(Template.TEMPLATE(), Template.Templates.join);
                                map.put(Template.Join.how, "LEFT");
                                map.put(Template.Join.joinTableAs, joinClass.getNameInDb());
                                map.put(Template.Join.joinColumnName, joinColumn.getColumnName());
                                map.put(Template.Join.mainTable, mainTable);
                                map.put(Template.Join.mainColumn, linkColumn.getColumnName());
                                map.put(Template.Join.joinTableName, joinClass.getNameInDb());
                                joinBody.add(map);
                            }
                        }
                        if (childLink.getKey().equals("str")) {
                            params.add("'" + childLink.getValue() + "'");
                        }
                        if (childLink.getKey().equals("num")) {
                            params.add(childLink.getValue());
                        }
                    }
                    s += StringUtils.join(params, ",") + ")";
                    re.add(s);
                }
            }
            if (child.getKey().equals("flow")) {
                String elseColumnId = child.getValue();
                String linkColumnId = child.getLink();
                Column linkColumn = columnMapper.selectById(linkColumnId);
                Class linkClass = classMapper.selectById(linkColumn.getClassId());
                StringBuilder s = new StringBuilder("(CASE `" + linkClass.getNameInDb() + "`.`" + linkColumn.getColumnName() + "`");
                List<ParamTree> childLinks = child.getLinks();
                if (StringUtils.isNotEmpty(elseColumnId)) {
                    Column column = columnMapper.selectById(elseColumnId);
                    Class aClass = classMapper.selectById(column.getClassId());
                    s = new StringBuilder("(CASE `" + aClass.getNameInDb() + "`.`" + column.getColumnName() + "`");
                    Map<String, String> map = new HashMap<>();
                    map.put(Template.TEMPLATE(), Template.Templates.join);
                    map.put(Template.Join.how, "LEFT");
                    map.put(Template.Join.joinTableAs, aClass.getNameInDb());
                    map.put(Template.Join.joinColumnName, column.getColumnName());
                    map.put(Template.Join.mainTable, mainTable);
                    map.put(Template.Join.mainColumn, linkColumn.getColumnName());
                    map.put(Template.Join.joinTableName, aClass.getNameInDb());
                    joinBody.add(map);
                }
                for (ParamTree childLink : childLinks) {
                    if (childLink.getKey().equals("when")) {
                        String str = " WHEN ";
                        String when = childLink.getWhen();
                        String type = childLink.getType();
                        String then = childLink.getValue();
                        String thenType = childLink.getThenType();
                        switch (type) {
                            case "str":
                                str += "'" + when + "'";
                                break;
                            case "num":
                                str += when;
                                break;
                            case "null":
                                str += "NULL";
                                break;
                            case "empty":
                                str += "''";
                                break;
                        }
                        switch (thenType) {
                            case "str":
                                str += " THEN '" + then + "'";
                                break;
                            case "num":
                                str += " THEN " + then;
                                break;
                            case "null":
                                str += " THEN " + "NULL";
                                break;
                            case "empty":
                                str += " THEN " + "''";
                                break;
                        }
                        s.append(str);
                    }
                    if (childLink.getKey().equals("else")) {
                        String str = " ELSE";
                        String then = childLink.getValue();
                        String thenType = childLink.getThenType();
                        switch (thenType) {
                            case "str":
                                str += " '" + then + "'";
                                break;
                            case "num":
                                str += " " + then;
                                break;
                            case "null":
                                str += " " + "NULL";
                                break;
                            case "empty":
                                str += " " + "''";
                                break;
                        }
                        s.append(str);
                    }
                }
                s.append(" END)AS `").append(tree.getName()).append("`");
                re.add(s.toString());
            }
        }
        for (int i = 0; i < joinBody.size(); i++) {
            String s = joinBody.get(i).get(Template.Join.joinTableName);
            if (s.equals(mainTable) && count.get(s) == null) {
                joinBody.get(i).put(Template.Join.joinTableName, s + "1");
                count.put(s, joinBody.size());
            } else if (count.get(s) == null) {
                joinBody.get(i).put(Template.Join.joinTableName, s + "1");
                count.put(s, joinBody.size());
            }
        }
        for (Map<String, String> map : joinBody) {
            String s = map.get(Template.Join.joinTableName);
            if (count.get(s) == null) {
                count.put(s, 1);
            } else if (s.equals(mainTable)) {
                count.put(s, 1);
            } else count.put(s, count.get(s) + 1);
        }
        for (Map<String, String> map : joinBody) {
            String s = map.get(Template.Join.joinTableName);
            if (count.get(s) == 0) {
                joins.add(clear(create(map)));
            } else {
                if (count.get(s) / joinBody.size() == 0) {
                    count.put(s, joinBody.size() + 1);
                } else {
                    count.put(s, count.get(s) + 1);
                }
                String name = map.get(Template.Join.joinTableName);
                map.put(Template.Join.joinTableName, name + count.get(s) % joinBody.size());
                joins.add(clear(create(map)));
            }
        }
        return StringUtils.join(re, ",");
    }

    private String getConditions(ParamTree tree) throws Exception {
        String interfaceId = tree.getInterfaceId();
        Interface anInterface = interfaceMapper.selectById(interfaceId);
        String classId = anInterface.getClassId();
        Class aClass = classMapper.selectById(classId);
        List<String> conditions = new ArrayList<>();
        List<ParamTree> links = tree.getLinks();
        for (ParamTree link : links) {
            String key = link.getKey();
            String where;
            String columnId = link.getLink();
            Column column = columnMapper.selectById(columnId);
            if (key.equals("condition")) {
                where = "`" + aClass.getNameInDb() + "`.`" + column.getColumnName() + "` ";
            } else if (key.equals("child")) {
                Class linkClass = classMapper.selectById(column.getClassId());
                String idColumn = linkClass.getIdColumn();
                if (idColumn == null) {
                    throw new Exception("如要添加子查询条件,请先设置" + linkClass.getNameInDb() + "表的id字段");
                }
                Column byId = columnMapper.selectById(idColumn);
                where = "(SELECT `" + column.getColumnName() + "` FROM `" + linkClass.getNameInDb() +
                        "` WHERE `" + byId.getColumnName() + "`= #{" + tree.getName() + "}) ";
            } else {
                continue;
            }
            if (link.getOperator().equals("IS NULL") || link.getOperator().equals("NOT IS NULL")) {
                where += link.getOperator() + " " + link.getEnd();
            } else {
                where += link.getOperator() + " #{" + tree.getName() + "} " + link.getEnd();
            }
            conditions.add(where);
        }
        if (conditions.size() == 0) return "";
        String re = StringUtils.join(conditions, " AND ");
        if (re.indexOf("(") < re.indexOf(")")) {
            re = "(" + re;
        }
        return re;
    }

    private String updateSql(Param param) throws Exception {
        ParamTree tree = JSON.parseObject(param.getJson(), ParamTree.class);
        String interfaceId = tree.getInterfaceId();
        Interface anInterface = interfaceMapper.selectById(interfaceId);
        String classId = anInterface.getClassId();
        Class aClass = classMapper.selectById(classId);
        List<String> conditions = new ArrayList<>();
        List<String> sets = new ArrayList<>();
        if (tree.getKey().equals("2") || tree.getKey().equals("4")) {
            if (tree.getKey().equals("2")) {
                tree.setName(entityMapper.selectById(tree.getName()).getName());
            }
            List<ParamTree> children = tree.getChildren();
            for (ParamTree child : children) {
                child.setInterfaceId(tree.getInterfaceId());
                String cond = getConditions(child);
                if (StringUtils.isNotEmpty(cond)) conditions.add(cond);
                sets.add(getSets(child));
            }
        } else {
            String cond = getConditions(tree);
            if (StringUtils.isNotEmpty(cond)) conditions.add(cond);
            sets.add(getSets(tree));
        }
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.update);
        map.put(Template.Update.tableName, aClass.getNameInDb());
        map.put(Template.Update.functionName, anInterface.getName());
        map.put(Template.Update.sets, StringUtils.join(sets, ","));
        if (conditions.size() == 0) {
            map.put(Template.Update.conditions, "");
        } else
            map.put(Template.Update.conditions, "WHERE " + StringUtils.join(conditions, " AND "));
        return create(map);
    }

    private String getSets(ParamTree tree) {
        List<ParamTree> links = tree.getLinks();
        if (links.size() == 1 && links.get(0).getKey().equals("link")) {
            String link = links.get(0).getLinks().get(0).getLink();
            Column column = columnMapper.selectById(link);
            return "`" + column.getColumnName() + "`=#{" + tree.getName() + "}";
        }
        return "getSets方法出错";
    }

    private String selectSql(Param out, Param in) throws Exception {
        if (out == null) {
            throw new Exception("select操作的回参不能为空");
        }
        ParamTree outTree = JSON.parseObject(out.getJson(), ParamTree.class);
        String interfaceId = outTree.getInterfaceId();
        Interface anInterface = interfaceMapper.selectById(interfaceId);
        String classId = anInterface.getClassId();
        Class aClass = classMapper.selectById(classId);
        List<String> conditions = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        List<String> joins = new ArrayList<>();
        List<String> results = new ArrayList<>();
        if (outTree.getKey().equals("2")) {
            String name = entityMapper.selectById(outTree.getName()).getName();
            outTree.setName(name);
            out.setName(name);
            for (ParamTree child : outTree.getChildren()) {
                results.add(getResults(child, joins, aClass.getNameInDb()));
            }
        } else if (outTree.getKey().equals("5")) {
            Class aClass1 = classMapper.selectById(outTree.getName());
            String name = aClass1.getNameInJava();
            outTree.setName(name);
            out.setName(name);
            List<Column> columns = columnMapper.getListByClassId(aClass1.getId());
            for (Column c : columns) {
                results.add("`"+c.getColumnName() + "` AS `" + c.getFiledName()+"`");
            }
        } else {
            results.add(getResults(outTree, joins, aClass.getNameInDb()));
        }
        if (in != null) {
            ParamTree inTree = JSON.parseObject(in.getJson(), ParamTree.class);
            if (inTree.getKey().equals("2") || inTree.getKey().equals("4")) {
                if (inTree.getKey().equals("2")) {
                    inTree.setName(entityMapper.selectById(inTree.getName()).getName());
                }
                for (ParamTree child : inTree.getChildren()) {
                    child.setInterfaceId(inTree.getInterfaceId());
                    String cond = getConditions(child);
                    if (StringUtils.isNotEmpty(cond)) conditions.add(cond);
                }
            } else {
                String cond = getConditions(inTree);
                if (StringUtils.isNotEmpty(cond)) conditions.add(cond);
            }
        }
        Project project = projectMapper.getMainProject();
        String s = project.getGroupId() + "." + project.getName();
        String typePath = s + ".work.param.out." + out.getName();
        map.put(Template.TEMPLATE(), Template.Templates.select);
        map.put(Template.Select.tableName, aClass.getNameInDb());
        map.put(Template.Select.functionName, anInterface.getName());
        map.put(Template.Select.as, aClass.getNameInDb());
        map.put(Template.Select.columns, StringUtils.join(results, ","));
        map.put(Template.Select.joins, StringUtils.join(joins, " "));
        map.put(Template.Select.typePath, typePath);
        if (conditions.size() == 0) {
            map.put(Template.Select.conditions, "");
        } else
            map.put(Template.Update.conditions, "WHERE " + StringUtils.join(conditions, " AND "));
        return create(map);
    }

    private String clear(String code) {
        return code.replaceAll(Pattern.quote("\n\n"), "\n");
    }

    private String nameCamel(String name) {
        StringBuilder sb = new StringBuilder(name);
        if (sb.charAt(0) == '_') sb.replace(0, 1, "");
        if (sb.charAt(sb.length() - 1) == '_') sb.replace(sb.length() - 1, sb.length(), "");
        int i = sb.indexOf("_");
        if (i != -1) {
            sb.replace(i, i + 2, (sb.charAt(i + 1) + "").toUpperCase());
            return nameCamel(sb.toString());
        }
        return name;
    }

    private String getParamName(String className) {
        if (className.length() == 0) return "";
        if (className.length() == 1) return className.toUpperCase();
        return (className.charAt(0) + "").toLowerCase() + className.substring(1);
    }

    private String aopCode(String path) throws Exception {
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.aop);
        map.put(Template.Aop.path, path);
        return clear(create(map));
    }

    private String responseCode(String path) throws Exception {
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.response);
        map.put(Template.Response.path, path);
        return clear(create(map));
    }

    private String appCode(String path, String projectName) throws Exception {
        Map<String, String> map = new HashMap<>();
        map.put(Template.TEMPLATE(), Template.Templates.application);
        map.put(Template.Application.groupId, path);
        map.put(Template.Application.projectName, projectName);
        map.put(Template.Application.comment, "/**\n" +
                " * @author Liberator\n" +
                " * @email 3451743380@qq.com\n" +
                " * @qq 3451743380\n" +
                " */");
        return clear(create(map));
    }
}
